//
//  APIRequest.m
//  ProjectDemo
//
//  Created by IOS3 on 2018/10/23.
//  Copyright © 2018 IOS3. All rights reserved.
//

#import "APIRequest.h"



#ifdef DEBUG
#define DLog(fmt, ...) NSLog((@"\n\n\n##########  class: < %s " "(%d) >" "   method: %s \n" fmt), [[NSString stringWithFormat:@"%s", __FILE__].lastPathComponent UTF8String], __LINE__,  __FUNCTION__, ##__VA_ARGS__);
#define DPrint(format, ...) printf("\n\n##########  class: < %s:(%d行) > method: %s \n%s\n", [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, __PRETTY_FUNCTION__, [[NSString stringWithFormat:(format), ##__VA_ARGS__] UTF8String] );
#else
#define DLog(...);
#define DPrint(...);
#endif


@implementation APIRequest


// ======  DEFAULT BASE URL =====
+ (NSURLSessionDataTask *)GET_default_final:(NSString *)uri params:(id)params complete:(void(^)(APIResponse *response))complete {
    return [self GET_default:uri params:params complete:^(APIResponse *response) {
        APIResponse *resp = [self finalHandleResponseObject:response];
        !complete ?: complete(resp);
    }];
}
+ (NSURLSessionDataTask *)POST_default_final:(NSString *)uri params:(id)params complete:(void(^)(APIResponse *response))complete {
    return [self POST_default:uri params:params complete:^(APIResponse *response) {
        APIResponse *resp = [self finalHandleResponseObject:response];
        !complete ?: complete(resp);
    }];
}
+ (APIResponse *)finalHandleResponseObject:(APIResponse *)response {
    if (response.responseObject) {
        response.finalResponse = true;
        // 对服务器返回的 responseObject 中对应错误吗进行处理
        //
    }
    return response;
}


+ (NSURLSessionDataTask *)GET_default:(NSString *)uri params:(id)params complete:(void(^)(APIResponse *response))complete {
    return [self defaultRequest:@"GET" uri:uri params:params complete:complete];
}
+ (NSURLSessionDataTask *)POST_default:(NSString *)uri params:(id)params complete:(void(^)(APIResponse *response))complete {
    return [self defaultRequest:@"POST" uri:uri params:params complete:complete];
}

+ (NSURLSessionDataTask *)defaultRequest:(NSString *)method uri:(NSString *)uri params:(id)params complete:(void(^)(APIResponse *response))complete {
    AFHTTPSessionManager *manager = [[APIRequestManager sharedInstance] sessionManagerWith:BaseURLType_default];
    return [self requestWithManager:manager method:method uri:uri params:params complete:complete];
}




// ======  UPLOAD BASE URL =====
//  data 图片对应的二进制数据
//  name 服务端需要参数
//  fileName 图片对应名字,一般服务不会使用,因为服务端会直接根据你上传的图片随机产生一个唯一的图片名字
//  mimeType 资源类型
//  不确定参数类型 可以这个 octet-stream 类型, 二进制流
+ (NSURLSessionDataTask *)uploadWith:(NSString *)uri params:(id)params progress:(void (^)(NSProgress *progress))progress formDataBlock:(NSDictionary<NSData *, NSString *> *(^)(id<AFMultipartFormData> formData, NSMutableDictionary<NSData *, NSString *> *needFillDataDict))formDataBlock complete:(void(^)(APIResponse *response))complete {
    static NSString *mineType = @"application/octet-stream";
    AFHTTPSessionManager *manager = [[APIRequestManager sharedInstance] sessionManagerWith:BaseURLType_upload];
    
    NSURLSessionDataTask * task = [manager POST:uri parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        NSMutableDictionary *needFillDataDict = [NSMutableDictionary dictionary];
        NSDictionary *datas = !formDataBlock ? nil : formDataBlock(formData, needFillDataDict);
        
        if (datas) {
            [datas enumerateKeysAndObjectsUsingBlock:^(NSData * _Nonnull data, NSString * _Nonnull name, BOOL * _Nonnull stop) {
                [formData appendPartWithFileData:data name:name fileName:@"random" mimeType:mineType];
            }];
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        dispatch_async(dispatch_get_main_queue(), ^{
            !progress ?: progress(uploadProgress);
        });
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self convertTask:task responseObject:responseObject error:nil complete:complete andLogWithManager:manager method:@"POST" uri:uri params:params];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self convertTask:task responseObject:nil error:error complete:complete andLogWithManager:manager method:@"POST" uri:uri params:params];
    }];
    return task;
}



/// 网络请求
+ (NSURLSessionDataTask *)requestWithManager:(AFHTTPSessionManager *)manager method:(NSString *)method uri:(NSString *)uri params:(id)params complete:(void(^)(APIResponse *response))complete {
    
    if (manager.reachabilityManager.networkReachabilityStatus == AFNetworkReachabilityStatusNotReachable) {
        APIResponse *response = [APIResponse new];
        response.error = [NSError errorWithDomain:NSCocoaErrorDomain code:-1 userInfo:nil];
        response.errorMsg = @"网络无法连接";
        !complete ?: complete(response);
        return nil;
    }
    
    NSURLSessionDataTask *task;
    if ([method isEqualToString:@"GET"]) {
        task = [manager GET:uri parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            [self convertTask:task responseObject:responseObject error:nil complete:complete andLogWithManager:manager method:method uri:uri params:params];
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [self convertTask:task responseObject:nil error:error complete:complete andLogWithManager:manager method:method uri:uri params:params];
        }];
    }
    else if ([method isEqualToString:@"POST"]) {
        task = [manager POST:uri parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            [self convertTask:task responseObject:responseObject error:nil complete:complete andLogWithManager:manager method:method uri:uri params:params];
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [self convertTask:task responseObject:nil error:error complete:complete andLogWithManager:manager method:method uri:uri params:params];
        }];
    }
    return task;
}


#pragma mark - 包装返回的数据
+ (void)convertTask:(NSURLSessionDataTask *)task responseObject:(id)responseObject error:(NSError *)error complete:(void(^)(APIResponse *response))complete andLogWithManager:(AFHTTPSessionManager *)manager method:(NSString *)method uri:(NSString *)uri params:(id)params {
#ifdef DEBUG
    [self logURL:method manager:manager uri:uri params:params];
#else
#endif

    APIResponse *response = [APIResponse new];
    response.finalResponse = false;
    
    NSObject *object = (NSObject *)responseObject;
    if (!object.isEmpty) {
        response.responseObject = object;
        DPrint(@"链接成功, \n%@", responseObject);
    }
    if (error) {
        response.error = error;
        DPrint(@"链接失败, \n%@", error);
    }
    if ([task.response isKindOfClass:[NSHTTPURLResponse class]]) {
        NSHTTPURLResponse *HTTPURLResponse = (NSHTTPURLResponse *)task.response;
        response.headers = HTTPURLResponse.allHeaderFields.mutableCopy;
    }

    !complete ?: complete(response);
}

// 打印请求链接
+ (void)logURL:(NSString *)method manager:(AFHTTPSessionManager *)manager uri:(NSString *)uri params:(id)params {
    NSString *baseURL = [manager.baseURL absoluteString];
    __block NSString *loger = [NSString stringWithFormat:@"%@: %@%@?", method, baseURL, uri];
    if ([params isKindOfClass:[NSDictionary class]]) {
        NSDictionary *dict = (NSDictionary *)params;
        [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            loger = [loger stringByAppendingFormat:@"%@=%@&", key, obj];
        }];
    }
    if ([loger hasSuffix:@"&"]) {
        loger = [loger substringToIndex:loger.length-1];
    }
    NSLog(@"\n\n\n##########  %@", loger);
    
}

@end
